namespace C1.Win.C1FlexGrid
{
    using C1.Win.C1FlexGrid.Util;
    using C1.Win.C1FlexGrid.Util.Styles;
    using System;
    using System.Collections;
    using System.Drawing;
    using System.Reflection;

    public class CellStyleCollection : IEnumerable
    {
        internal GridModel _grid;
        internal StyleContext _styleCtx;
        internal ArrayList _styles;

        internal CellStyleCollection(GridModel grid)
        {
            this.CreateStyleContext();
            this.Attach(grid);
        }

        public CellStyleCollection(string str)
        {
            this.CreateStyleContext();
            this.ParseString(str);
        }

        public CellStyle Add(string name)
        {
            return this.Add(name, null);
        }

        public CellStyle Add(string name, CellStyle basedOn)
        {
            int num = this.Find(name);
            if (num >= 0)
            {
                return this[num];
            }
            if (!NameIsValid(name))
            {
                throw new ArgumentException("Invalid style name.");
            }
            Style style = this._styleCtx.AddStyle(name, this.Normal._style);
            this._styles.Add(style);
            if (basedOn != null)
            {
                style._atts = (Hashtable) basedOn._style._atts.Clone();
            }
            return new CellStyle(style);
        }

        internal Style AddInternal()
        {
            return this._styleCtx.AddStyle(null, this.Normal._style);
        }

        internal void Attach(GridModel grid)
        {
            if ((this._grid != null) && (this._styleCtx != null))
            {
                this._styleCtx.StyleChanged -= new StyleEventHandler(this._grid.OnStyleChanged);
            }
            this._grid = grid;
            if ((this._grid != null) && (this._styleCtx != null))
            {
                this._styleCtx.StyleChanged += new StyleEventHandler(this._grid.OnStyleChanged);
                this._grid.NotifyViews(GridChangedTypeEnum.RepaintGrid);
            }
        }

        public string BuildString(bool includeEmpty)
        {
            string str = string.Empty;
            for (int i = 0; i < this.Count; i++)
            {
                string name = this[i].Name;
                if ((name != null) && (name.Length != 0))
                {
                    string str3 = this[i].BuildString();
                    if (includeEmpty || (str3.Length != 0))
                    {
                        string str4 = str;
                        str = str4 + name + "{" + str3 + "}\t";
                    }
                }
            }
            return str;
        }

        public void Clear()
        {
            int index = 15;
            while (this.Count > index)
            {
                this.Remove(index);
            }
            bool flag = false;
        Label_007C:
            while (!flag)
            {
                flag = true;
                foreach (Style style in this._styleCtx.GetStyles())
                {
                    string name = style.GetName();
                    if (!this.Contains(name))
                    {
                        this._styleCtx.RemoveStyle(name);
                        flag = false;
                        goto Label_007C;
                    }
                }
            }
            this.InitializeBuiltIns();
        }

        public bool Contains(string name)
        {
            return (this.Find(name) >= 0);
        }

        internal void CreateStyleContext()
        {
            this._styleCtx = new StyleContext();
            this._styles = new ArrayList();
            Style baseStyle = this._styleCtx.GetBaseStyle();
            baseStyle.SetAttribute("Wrap", false);
            baseStyle.SetAttribute("Padding", new Margins(2, 2, 0, 0));
            baseStyle.SetAttribute("AlignVert", AlignVertEnum.Center);
            baseStyle.SetAttribute("Border", new Border(SystemBrushes.Control, 0, 1, 0, 1));
            Style style2 = this._styleCtx.AddStyle("Normal");
            this._styles.Add(style2);
            baseStyle = this._styleCtx.AddStyle("Alternate", style2);
            this._styles.Add(baseStyle);
            baseStyle = this._styleCtx.AddStyle("Fixed", style2);
            this._styles.Add(baseStyle);
            baseStyle = this._styleCtx.AddStyle("Highlight", style2);
            this._styles.Add(baseStyle);
            baseStyle = this._styleCtx.AddStyle("Focus", style2);
            this._styles.Add(baseStyle);
            baseStyle = this._styleCtx.AddStyle("Search", style2);
            this._styles.Add(baseStyle);
            baseStyle = this._styleCtx.AddStyle("Frozen", style2);
            this._styles.Add(baseStyle);
            baseStyle = this._styleCtx.AddStyle("EmptyArea", style2);
            this._styles.Add(baseStyle);
            baseStyle = this._styleCtx.AddStyle("GrandTotal", style2);
            this._styles.Add(baseStyle);
            for (int i = 0; i <= 5; i++)
            {
                baseStyle = this._styleCtx.AddStyle(string.Format("Subtotal{0}", i), style2);
                this._styles.Add(baseStyle);
            }
            this.InitializeBuiltIns();
        }

        internal int Find(string name)
        {
            for (int i = 0; i < this._styles.Count; i++)
            {
                Style style = (Style) this._styles[i];
                if (string.Compare(name, style.GetName(), true) == 0)
                {
                    return i;
                }
            }
            return -1;
        }

        public int IndexOf(CellStyle style)
        {
            return this._styles.IndexOf(style._style);
        }

        internal void InitializeBuiltIns()
        {
            this.Fixed.BackColor = SystemColors.Control;
            this.Fixed.ForeColor = SystemColors.ControlText;
            this.Fixed.Border.Color = SystemColors.ControlDark;
            this.Highlight.BackColor = SystemColors.Highlight;
            this.Highlight.ForeColor = SystemColors.HighlightText;
            this.Search.BackColor = SystemColors.Highlight;
            this.Search.ForeColor = SystemColors.HighlightText;
            this.Frozen.BackColor = Color.Beige;
            this.EmptyArea.BackColor = SystemColors.AppWorkspace;
            this.EmptyArea.Border.Color = SystemColors.ControlDarkDark;
            CellStyle style = this[CellStyleEnum.GrandTotal];
            style.BackColor = Color.Black;
            style.ForeColor = Color.White;
            for (int i = 0; i <= 5; i++)
            {
                style = this[(CellStyleEnum) (9 + i)];
                style.BackColor = SystemColors.ControlDarkDark;
                style.ForeColor = Color.White;
            }
        }

        internal static bool NameIsValid(string name)
        {
            char[] anyOf = new char[] { '{', '}' };
            return ((name.Length > 0) && (name.IndexOfAny(anyOf) < 0));
        }

        public bool ParseString(string str)
        {
            while (true)
            {
                int index = str.IndexOf('{');
                int num2 = str.IndexOf('}');
                if ((index < 0) || (num2 < 0))
                {
                    break;
                }
                string item = str.Substring(0, index).Trim();
                string str3 = str.Substring(index + 1, (num2 - index) - 1).Trim();
                CellStyle style = this._styles.Contains(item) ? this[item] : this.Add(item);
                style.Clear();
                style.ParseString(str3);
                str = str.Substring(num2 + 1);
            }
            return true;
        }

        public void Remove(CellStyle style)
        {
            int index = this.IndexOf(style);
            if (index < 0)
            {
                throw new IndexOutOfRangeException("Style not found in Collection.");
            }
            this.Remove(index);
        }

        public void Remove(int index)
        {
            int num2;
            int num = 15;
            if (index < num)
            {
                throw new IndexOutOfRangeException("Can't remove built-in styles.");
            }
            Style style = (Style) this._styles[index];
            for (num2 = 0; num2 < this._grid._rows.Count; num2++)
            {
                if (this._grid._rows[num2]._style == style)
                {
                    this._grid._rows[num2]._style = null;
                }
            }
            int col = 0;
            while (col < this._grid._cols.Count)
            {
                if (this._grid._cols[col]._style == style)
                {
                    this._grid._cols[col]._style = null;
                }
                col++;
            }
            for (num2 = 0; num2 < this._grid._rows.Count; num2++)
            {
                for (col = 0; col < this._grid._cols.Count; col++)
                {
                    if (this._grid.GetCellStyle(num2, col) == style)
                    {
                        this._grid.SetCellStyle(num2, col, null);
                    }
                }
            }
            this._styleCtx.RemoveStyle((Style) this._styles[index]);
            this._styles.RemoveAt(index);
        }

        public void Remove(string name)
        {
            int index = this.Find(name);
            if (index < 0)
            {
                throw new IndexOutOfRangeException("Style not found in Collection.");
            }
            this.Remove(index);
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new CellStyleEnumerator(this._styles);
        }

        public CellStyle Alternate
        {
            get
            {
                return this[CellStyleEnum.Alternate];
            }
        }

        internal CellStyle Base
        {
            get
            {
                return new CellStyle(this._styleCtx.GetBaseStyle());
            }
        }

        public int Count
        {
            get
            {
                return this._styles.Count;
            }
        }

        public CellStyle EmptyArea
        {
            get
            {
                return this[CellStyleEnum.EmptyArea];
            }
        }

        public CellStyle Fixed
        {
            get
            {
                return this[CellStyleEnum.Fixed];
            }
        }

        public CellStyle Focus
        {
            get
            {
                return this[CellStyleEnum.Focus];
            }
        }

        public CellStyle Frozen
        {
            get
            {
                return this[CellStyleEnum.Frozen];
            }
        }

        public CellStyle Highlight
        {
            get
            {
                return this[CellStyleEnum.Highlight];
            }
        }

        public CellStyle this[string name]
        {
            get
            {
                if (this.Find(name) < 0)
                {
                    return null;
                }
                return new CellStyle(this._styleCtx.GetStyle(name));
            }
        }

        public CellStyle this[CellStyleEnum index]
        {
            get
            {
                return this[(int) index];
            }
        }

        public CellStyle this[int index]
        {
            get
            {
                return new CellStyle((Style) this._styles[index]);
            }
        }

        public CellStyle Normal
        {
            get
            {
                return this[CellStyleEnum.Normal];
            }
        }

        public CellStyle Search
        {
            get
            {
                return this[CellStyleEnum.Search];
            }
        }

        public Color TransparentColor
        {
            get
            {
                return this._styleCtx.TransparentColor;
            }
            set
            {
                this._styleCtx.TransparentColor = value;
            }
        }
    }
}

